<?php

namespace app\admin\controller\unilive;

use app\common\controller\Backend;
use EasyWeChat\Factory;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 直播商品管理
 *
 * @icon fa fa-circle-o
 */
class Goods extends Backend
{
    /**
     * Goods模型对象
     * @var \app\admin\model\unilive\Goods
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\unilive\Goods;
        $this->view->assign("auditStatusList", $this->model->getAuditStatusList());
        $this->view->assign("thirdPartyTagList", $this->model->getThirdPartyTagList());
        $this->view->assign("priceTypeList", $this->model->getPriceTypeList());
    }


    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                try {

                    $config = get_addon_config('unilive');
                    $app = Factory::miniProgram($config);
                    $goodsParams['goodsInfo'] = [
                        "name" => $params['name'], // 商品名称，最长14个汉字，1个汉字相当于2个字符
                        "coverImgUrl" => $params['coverImgUrl'], // 填入mediaID
                        "priceType" => $params['priceType'], // 价格类型，1：一口价，2：价格区间，3：显示折扣价；1：一口价，只需要传入price，price2不传；2：价格区间，price字段为左边界，price2字段为右边界，price和price2必传。3：折扣价，price字段为原价，price2字段为现价， price和price2必传
                        "price" => $params['price'],
                        "price2" => $params['price2'],
                        "url" => $params['url'],
                    ];
                    $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/add', $goodsParams);

                    if (isset($goods['errcode'])) {
                        if ($goods['errcode'] != 0) {
                            $this->error($goods['errmsg'].':'.$goods['errcode']);
                        }
                    } else {
                        throw new Exception($goods);
                    }

                    $coverImgUrl = \app\admin\model\unilive\Media::getByMediaId($params['coverImgUrl']);
                    $params['coverImgUrl_media_id'] = $params['coverImgUrl'];
                    $params['coverImgUrl'] = $coverImgUrl['path'] ?? $params['coverImgUrl'];

                    $params['goodsId'] = $goods['goodsId'];
                    $params['auditId'] = $goods['auditId'];
                    $params['audit_status'] = 1; // 默认审核中
                    $params['third_party_tag'] = 2; // 表示为api添加的商品

                    $result = false;
                    Db::startTrans();
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                        $this->model->validateFailException(true)->validate($validate);
                    }
                    $result = $this->model->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        return $this->view->fetch();
    }


    /**
     * 复制
     */
    public function copy($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                try {

                    $config = get_addon_config('unilive');
                    $app = Factory::miniProgram($config);
                    $goodsParams['goodsInfo'] = [
                        "name" => $params['name'], // 商品名称，最长14个汉字，1个汉字相当于2个字符
                        "coverImgUrl" => $params['coverImgUrl'], // 填入mediaID
                        "priceType" => $params['priceType'], // 价格类型，1：一口价，2：价格区间，3：显示折扣价；1：一口价，只需要传入price，price2不传；2：价格区间，price字段为左边界，price2字段为右边界，price和price2必传。3：折扣价，price字段为原价，price2字段为现价， price和price2必传
                        "price" => $params['price'],
                        "price2" => $params['price2'],
                        "url" => $params['url'],
                    ];
                    $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/add', $goodsParams);

                    if (isset($goods['errcode'])) {
                        if ($goods['errcode'] != 0) {
                            $this->error($goods['errmsg'].':'.$goods['errcode']);
                        }
                    } else {
                        throw new Exception($goods);
                    }

                    $coverImgUrl = \app\admin\model\unilive\Media::getByMediaId($params['coverImgUrl']);
                    $params['coverImgUrl_media_id'] = $params['coverImgUrl'];
                    $params['coverImgUrl'] = $coverImgUrl['path'] ?? $params['coverImgUrl'];

                    $params['goodsId'] = $goods['goodsId'];
                    $params['auditId'] = $goods['auditId'];
                    $params['audit_status'] = 1; // 默认审核中
                    $params['third_party_tag'] = 2; // 表示为api添加的商品

                    $result = false;
                    Db::startTrans();

                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                        $this->model->validateFailException(true)->validate($validate);
                    }
                    $result = $this->model->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 撤回审核
     */
    public function recall($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        try {
            $config = get_addon_config('unilive');
            $app = Factory::miniProgram($config);
            $goodsParams = [
                "goodsId" => $row['goodsId'], // 商品ID
                "auditId" => $row['auditId'], // 审核单ID
            ];
            $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/resetaudit', $goodsParams);
            if (isset($goods['errcode'])) {
                if ($goods['errcode'] != 0) {
                    $this->error($goods['errmsg'].':'.$goods['errcode']);
                } else {
                    $row->audit_status = 0; // 未审核
                    $row->save();
                    $this->success('撤回成功');
                }
            } else {
                throw new Exception($goods);
            }

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 重新提交审核
     */
    public function resubmit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        try {
            $config = get_addon_config('unilive');
            $app = Factory::miniProgram($config);
            $goodsParams = [
                "goodsId" => $row['goodsId'], // 商品ID
            ];
            $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/audit', $goodsParams);
            if (isset($goods['errcode'])) {
                if ($goods['errcode'] != 0) {
                    $this->error($goods['errmsg']. ':'.$goods['errcode']);
                } else {
                    $row->audit_status = 1; // 审核中
                    $row->auditId = $goods['auditId'];

                    $row->save();
                    $this->success('重新提交审核成功');
                }

            } else {
                throw new Exception($goods);
            }

        } catch (Exception $e) {
            $this->error($e->getMessage());

        }
    }


    /**
     * 删除
     */
    public function del($ids = "")
    {
        if ($ids) {
            $pk = $this->model->getPk();
            $adminIds = $this->getDataLimitAdminIds();
            if (is_array($adminIds)) {
                $this->model->where($this->dataLimitField, 'in', $adminIds);
            }
            $list = $this->model->where($pk, 'in', $ids)->select();

            $count = 0;
            Db::startTrans();
            try {
                $config = get_addon_config('unilive');
                $app = Factory::miniProgram($config);

                foreach ($list as $k => $v) {
                    $goodsParams = [
                        "goodsId" => $v['goodsId'], // 商品ID
                    ];
                    $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/delete', $goodsParams);
                    if (isset($goods['errcode'])) {
                        if ($goods['errcode'] != 0) {
                            throw new Exception($goods['errmsg']. ':'. $goods['errcode']);
                        }
                    } else {
                        throw new Exception($goods);
                    }

                    $count += $v->delete();
                }
                Db::commit();
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                $this->success();
            } else {
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }


    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                try {
                    $params = $this->preExcludeFields($params);

                    $config = get_addon_config('unilive');
                    $app = Factory::miniProgram($config);
                    $goodsParams['goodsInfo'] = [
                        "name" => $params['name'], // 商品名称，最长14个汉字，1个汉字相当于2个字符
                        "coverImgUrl" => $params['coverImgUrl'], // 填入mediaID
                        "priceType" => $params['priceType'], // 价格类型，1：一口价，2：价格区间，3：显示折扣价；1：一口价，只需要传入price，price2不传；2：价格区间，price字段为左边界，price2字段为右边界，price和price2必传。3：折扣价，price字段为原价，price2字段为现价， price和price2必传
                        "price" => $params['price'],
                        "price2" => $params['price2'],
                        "url" => $params['url'],
                        "goodsId" => $row['goodsId'],
                    ];
                    foreach ($goodsParams['goodsInfo'] as $key => $value) {
                        if (empty($value) || $value == '') {
                            unset($goodsParams['goodsInfo'][$key]);
                        }
                    }
                    $goods = $app->subscribe_message->httpPostJson('wxaapi/broadcast/goods/update', $goodsParams);
                    if (isset($goods['errcode'])) {
                        if ($goods['errcode'] != 0) {
                            $this->error($goods['errmsg'] . $goods['errcode']);
                        }
                    } else {
                        throw new Exception($goods);
                    }
                    $coverImgUrl = \app\admin\model\unilive\Media::getByMediaId($params['coverImgUrl']);
                    $params['coverImgUrl_media_id'] = $params['coverImgUrl'];
                    $params['coverImgUrl'] = $coverImgUrl['path'] ?? $params['coverImgUrl'];

                    $result = false;
                    Db::startTrans();
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }
                    $result = $row->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 获取商品状态
     */
    public function getgoodswarehouse($ids = "")
    {
        if ($ids) {
            $pk = $this->model->getPk();
            $adminIds = $this->getDataLimitAdminIds();
            if (is_array($adminIds)) {
                $this->model->where($this->dataLimitField, 'in', $adminIds);
            }
            $list = $this->model->where($pk, 'in', $ids)->select();

            $count = 0;
            Db::startTrans();
            try {
                $config = get_addon_config('unilive');
                $app = Factory::miniProgram($config);

                $goodsParams["goods_ids"] = [];
                foreach ($list as $k => $v) {
                    $goodsParams["goods_ids"][] = $v['goodsId'];
                }
                $goods = $app->subscribe_message->httpPostJson('wxa/business/getgoodswarehouse', $goodsParams);

                if (isset($goods['errcode'])) {
                    if ($goods['errcode'] != 0) {
                        $this->error($goods['errmsg'].':'.$goods['errcode']);
                    }
                    // 量不多，直接循环 O(n^2)
                    foreach ($goods['goods'] as $good) {
                        foreach ($list as $k => $v) {
                            if ($good['goods_id'] == $v['goodsId']) {
                                $v->coverImgUrl = $good['cover_img_url'];
                                $v->name = $good['name'];
                                $v->price = $good['price'];
                                $v->url = $good['url'];
                                $v->priceType = $good['price_type'];
                                $v->price2 = $good['price2'];
                                $v->audit_status = $good['audit_status'];
                                $v->third_party_tag = $good['third_party_tag'];
                                $v->save();
                                $count++;
                            }
                        }
                    }

                } else {
                    throw new Exception($goods);
                }

                Db::commit();
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                $this->success();
            } else {
                $this->error(__('No rows were updated'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }

    /**
     * 选择商品
     */
    public function select()
    {
        if ($this->request->isAjax()) {
            return $this->index();
        }
        return $this->view->fetch();
    }


    /**
     * 同步
     */
    public function sync()
    {
        try {
            $config = get_addon_config('unilive');
            $app = Factory::miniProgram($config);

            $goodsModel = new \app\admin\model\unilive\Goods();
            $oldGoods = $goodsModel::column('id,coverImgUrl_media_id,auditId,audit_status', 'goodsId');

            $insertData = [];
            for($i = 0 ; $i < 4 ; $i++) {
                $offset = 0;
                $limit = 100;
                while (1) {
                    $goods = $app->subscribe_message->httpGet('wxaapi/broadcast/goods/getapproved',['offset' => $offset, 'limit' => $limit, 'status' => $i]);
                    if (isset($goods['errcode']) && $goods['errcode'] == 0 && !empty($goods['goods'])) {
                        foreach ($goods['goods'] as $good) {
                            $insertData[] = [
                                'id' => $oldGoods[$good['goodsId']]['id'] ?? 0,
                                'goodsId' => $good['goodsId'],
                                'coverImgUrl' => $good['coverImgUrl'],
                                'name' => $good['name'],
                                'price' => $good['price'],
                                'url' => $good['url'],
                                'priceType' => $good['priceType'],
                                'price2' => $good['price2'],
                                'third_party_tag' => $good['thirdPartyTag'],
                                'coverImgUrl_media_id' => $oldGoods[$good['goodsId']]['coverImgUrl_media_id'] ?? '',
                                'auditId' => $oldGoods[$good['goodsId']]['auditId'] ?? '',
                                'audit_status' => $i,
                            ];
                            if (isset($oldGoods[$good['goodsId']])) {
                                unset($oldGoods[$good['goodsId']]);
                            }
                        }

                    } else {
                        if (isset($goods['errmsg'])) {
                            throw new Exception($goods['errmsg'].':'.$goods['errcode']);
                        }
                        break;
                    }
                    if (isset($goods['total']) && $goods['total'] <= $limit) {
                        break;
                    }
                    $offset = $limit;
                    $limit = $limit + $limit;
                }
            }
            $goodsModel->insertAll($insertData, 'REPLACE');

            if (!empty($oldGoods)) {
                $id = array_column($oldGoods, 'id');
                $id = implode(',', $id);
                $goodsModel->where('id in (' . $id . ')')->delete();
            }

            $this->success('同步成功');

        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }
}
